home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / shells / rc-1.000 / rc-1 / rc-1.5-linux / status.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-07  |  3.3 KB  |  148 lines

  1. /* status.c: functions for printing fancy status messages in rc */
  2.  
  3. #include "rc.h"
  4. #include "sigmsgs.h"
  5.  
  6. /* status == the wait() value of the last command in the pipeline, or the last command */
  7.  
  8. static int statuses[512];
  9. static int pipelength = 1;
  10.  
  11. /*
  12.    Test to see if rc's status is true. According to td, status is true
  13.    if and only if every pipe-member has an exit status of zero.
  14. */
  15.  
  16. extern int istrue() {
  17.     int i;
  18.     for (i = 0; i < pipelength; i++)
  19.         if (statuses[i] != 0)
  20.             return FALSE;
  21.     return TRUE;
  22. }
  23.  
  24. /*
  25.    Return the status as an integer. A status which has low-bits set is
  26.    a signal number, whereas a status with high bits set is a value set
  27.    from exit(). The presence of a signal just sets status to 1. Also,
  28.    a pipeline with nonzero exit statuses in it just sets status to 1.
  29. */
  30.  
  31. extern int getstatus() {
  32.     int s;
  33.     if (pipelength > 1)
  34.         return !istrue();
  35.     s = statuses[0];
  36.     return (s&0xff) ? 1 : (s >> 8) & 0xff;
  37. }
  38.  
  39. extern void set(bool code) {
  40.     setstatus(-1, (!code) << 8); /* exit status 1 == 0x100 */
  41. }
  42.  
  43. /* take a pipeline and store the exit statuses. Check to see whether any of the children dumped core */
  44.  
  45. extern void setpipestatus(int stats[], int num) {
  46.     int i;
  47.     for (i = 0; i < (pipelength = num); i++) {
  48.         statprint(-1, stats[i]);
  49.         statuses[i] = stats[i];
  50.     }
  51. }
  52.  
  53. /* set a simple status, as opposed to a pipeline */
  54.  
  55. extern void setstatus(int pid, int i) {
  56.     pipelength = 1;
  57.     statuses[0] = i;
  58.     statprint(pid, i);
  59. }
  60.  
  61. /* print a message if termination was with a signal, and if the child dumped core. exit on error if -e is set */
  62.  
  63. extern void statprint(int pid, int i) {
  64.     if (i & 0xff) {
  65.         char *msg = ((i & 0x7f) < NUMOFSIGNALS ? signals[i & 0x7f].msg : "");
  66.         if (pid != -1)
  67.             fprint(2, "%d: ", pid);
  68.         if (i & 0x80) {
  69.             if (*msg == '\0')
  70.                 fprint(2, "core dumped\n");
  71.             else
  72.                 fprint(2, "%s--core dumped\n", msg);
  73.         } else if (*msg != '\0')
  74.             fprint(2, "%s\n", msg);
  75.     }
  76.     if (i != 0 && dashee && !cond)
  77.         rc_exit(getstatus());
  78. }
  79.  
  80. /* prepare a list to be passed back. Used whenever $status is dereferenced */
  81.  
  82. extern List *sgetstatus() {
  83.     List *r = NULL;
  84.     int i;
  85.  
  86.     for (i = 0; i < pipelength; i++) {
  87.         List *q = nnew(List);
  88.         q->w = strstatus(statuses[i]);
  89.         q->m = NULL;
  90.         q->n = r;
  91.         r = q;
  92.     }
  93.  
  94.     return r;
  95. }
  96.  
  97. /* return status as a string (used above and for bqstatus) */
  98.  
  99. extern char *strstatus(int s) {
  100.     int t = s & 0x7f;
  101.  
  102.     if (t != 0) {
  103.         const char *core = (s & 0x80) ? "+core" : "";
  104.         if (t < NUMOFSIGNALS && *signals[t].name != '\0')
  105.             return nprint("%s%s", signals[t].name, core);
  106.         else
  107.             return nprint("-%d%s", t, core); /* unknown signals are negated */
  108.     } else
  109.         return nprint("%d", (s >> 8) & 0xff);
  110. }
  111.  
  112. extern void ssetstatus(char **av) {
  113.     int i, j, k, l;
  114.     bool found;
  115.     for (l = 0; av[l] != NULL; l++)
  116.         ; /* count up array length */
  117.     --l;
  118.     for (i = 0; av[i] != NULL; i++) {
  119.         j = a2u(av[i]);
  120.         if (j >= 0) {
  121.             statuses[l - i] = j << 8;
  122.             continue;
  123.         }
  124.         found = FALSE;
  125.         for (k = 0; k < NUMOFSIGNALS; k++) {
  126.             if (streq(signals[k].name, av[i])) {
  127.                 statuses[l - i] = k;
  128.                 found = TRUE;
  129.                 break;
  130.             } 
  131.             else {
  132.                 SIZE_T len = strlen(signals[k].name);
  133.                 if (strncmp(signals[k].name, av[i], len) == 0 && streq(av[i] + len, "+core")) {
  134.                     statuses[l - i] = k + 0x80;
  135.                     found = TRUE;
  136.                     break;
  137.                 }
  138.             }
  139.         }
  140.         if (!found) {
  141.             fprint(2, "bad status\n");
  142.             set(FALSE);
  143.             return;
  144.         }
  145.     }
  146.     pipelength = i;
  147. }
  148.